﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using System.Reflection;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace VncTab
{
	public partial class App : Application
	{
		private const int MemSize = 4096;
		private System.IO.MemoryMappedFiles.MemoryMappedFile file;
		private EventWaitHandle signal;
		string signalName = "signal" + Assembly.GetCallingAssembly().GetName().Name;

		protected override void OnLoadCompleted(System.Windows.Navigation.NavigationEventArgs e)
		{
			base.OnLoadCompleted(e);
		}

		protected override void OnStartup(StartupEventArgs e)
		{
			try
			{
				this.file = System.IO.MemoryMappedFiles.MemoryMappedFile.OpenExisting("argFile" + Assembly.GetCallingAssembly().GetName().Name);
				this.signal = EventWaitHandle.OpenExisting(signalName);

				BinaryFormatter formatter = new BinaryFormatter();
				using (var memStream = new MemoryStream())
				{
					formatter.Serialize(memStream, e.Args);
					byte[] bytes = memStream.ToArray();
					memStream.Close();
					using (var writer = file.CreateViewAccessor(0, MemSize + 4))
					{
						var lenght = bytes.Length;
						writer.Write<int>(0, ref lenght);
						writer.WriteArray<byte>(4, bytes, 0, bytes.Length);
					}
				}

				this.signal.Set();
				Current.Shutdown();
				return;
			}
			catch
			{
				this.Arguments = e.Args;
				this.file = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpen("argFile" + Assembly.GetCallingAssembly().GetName().Name, MemSize + 4);
				this.signal = new EventWaitHandle(false, EventResetMode.AutoReset, signalName);
				ThreadPool.QueueUserWorkItem((_) =>
				{
					while (true)
					{
						signal.WaitOne();
						using (var reader = file.CreateViewAccessor())
						{
							var length = reader.ReadInt32(0);
							byte[] bytes = new byte[length];
							reader.ReadArray<byte>(4, bytes, 0, length);
							using (MemoryStream memStream = new MemoryStream(bytes))
							{
								memStream.Seek(0, SeekOrigin.Begin);

								BinaryFormatter formatter = new BinaryFormatter();
								try
								{
									Dispatcher.Invoke((Action)(() => (MainWindow as MainWindow).HandleArguments(formatter.Deserialize(memStream) as string[])), System.Windows.Threading.DispatcherPriority.Background);
								}
								catch
								{
								}
							}
						}
					}
				});
			};

			Console.WriteLine("usage vnctab /d=<remotehostName> /p=<password> /w=<windowwidth> /h=<windowheight> /l=<windowleft< /t=<windowtop> /r=<true|false>");
			ThreadPool.QueueUserWorkItem((_) =>
			{
				Thread.Sleep(1000);
				Dispatcher.BeginInvoke((Action)(() => (MainWindow as MainWindow).HandleArguments(this.Arguments)), System.Windows.Threading.DispatcherPriority.Background);
			});
			base.OnStartup(e);
		}

		public string[] Arguments { get; private set; }
	}
}
